﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using NetflixCatalogExplorer;
using IPickImporterUI.UtilObjects;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
using System.Data.Services.Client;
using IPickImporterUI.NetFlixCatalog;
using System.Threading.Tasks;

namespace IPickImporterUI.NetFlix
{
    class NetFlixImporter
    {

#region "Private Variables and Properties"
        private static string wsCatalogPath = "http://odata.netflix.com/Catalog";
        private Int64 countToRetrieve = 10000;
        public readonly string appConnStr = ConfigurationManager.ConnectionStrings["IPickConnStr"].ConnectionString;
#endregion

 #region "Methods"

        /// <summary>
        /// Manages the different steps of the Import Process
        /// </summary>
        /// <returns></returns>
        public string ProcessImport()
        {

            string result = "";
            DataLayer oDataLayer = new DataLayer();


            //Clean the staging table
            result = oDataLayer.ClearTemporaryTable();
            if (!String.IsNullOrWhiteSpace(result))
            {
                return result;
            }

            //Build the Catalog From NetFlix
            DataTable dtCatalog = BuildCataLog(countToRetrieve);

            //Bulk Import the Data
            result += oDataLayer.BulkImportData(dtCatalog);
            if (!String.IsNullOrWhiteSpace(result))
            {
                return result;
            }


            //Synch the Data with the real tables
            result = oDataLayer.SynchCatalogTables();
            if (!String.IsNullOrWhiteSpace(result))
            {
                return result;
            }

            return result;

        }// end ProcessImport



        /// <summary>
        /// Magical retrieval and Continuity from NetFlix's OData
        /// </summary>
        /// <param name="howMany"></param>
        /// <returns></returns>
        public static IEnumerable<Title> GetTitles(Int64 howMany)
        {
            var context = new NetflixCatalog(new Uri(wsCatalogPath));
            DataServiceQueryContinuation<Title> token = null;
            var response = ((from title in context.Titles select title) as DataServiceQuery<Title>)
                .Expand("Genres,Cast,Directors")
                .Execute() as QueryOperationResponse<Title>;
            int count = 0;
            var ids = new HashSet<string>();
            do
            {
                if (token != null)
                {
                    response = (QueryOperationResponse<Title>)context.Execute<Title>(new UriBuilder(token.NextLinkUri) { Port = 80 }.Uri);
                }
                foreach (var title in response)
                {
                    if (ids.Add(title.Id))
                    {
                        if (count < howMany)
                        {
                            yield return title;
                        }
                        count++;
                    }
                }
                token = response.GetContinuation();
            }
            while (token != null && count < howMany);
        }



        /// <summary>
        /// Build the Catalog, by querying NetFlix
        /// </summary>
        /// <param name="howMany"></param>
        /// <returns></returns>
        private DataTable BuildCataLog(Int64 howMany)
        {

            List<Catalog> catalogList = new List<Catalog>();

            //WOW....Parallel Processing.....
            Parallel.ForEach(GetTitles(howMany), new ParallelOptions { MaxDegreeOfParallelism = 16 }, (title) =>
            {
                Catalog singleCataLog = null;
                singleCataLog = new Catalog(
                                                0,
                                                title.Id,
                                                title.Name,
                                                title.BoxArt.SmallUrl,
                                                title.BoxArt.MediumUrl,
                                                title.BoxArt.LargeUrl,
                                                Convert.ToInt16(title.ReleaseYear),
                                                title.Rating,
                                                title.Synopsis,
                                                title.AverageRating.ToString()
                                           );

                catalogList.Add(singleCataLog);
            });

            //convert to a DataTable
            return SimpleConverter.ConvertToDataTable(catalogList.ToArray());

        } //End BuildCataLog
  #endregion
       

       
    }
}
